﻿#include "OiPCH.hpp"

namespace Oi
{
    namespace PLScannerCore
    {
        class loginDlg : public QDialog
        {
        public:
            loginDlg(QWidget* parent);

        public:
            QComboBox* id;
            Ctrl::TouchInput* password;
            QDialogButtonBox* buttons;
        };

        class UserEditDlg : public QDialog
        {
        public:
            UserEditDlg(QWidget* parent);

            void setEditable(bool);

            void setParams(const UserParams& mp);

            void params(UserParams& mp);

        public:
            Ctrl::TouchInput* id;
            Ctrl::TouchInput* name;
            QComboBox* type;
            QComboBox* classes;
            Ctrl::TouchInput* password;
            QDialogButtonBox* buttons;
        };

        class PermissionEditDlg : public QDialog
        {
        public:
            PermissionEditDlg(QWidget* parent);

            void setPermission(const int& mp);

            void permission(int& mp);

        public:
            QCheckBox* _addDelFormular;
            QCheckBox* _modifyFormular;
            QCheckBox* _viewData;
            QCheckBox* _viewStatistics;
            QCheckBox* _viewFPYStatistics;
            QCheckBox* _viewTimeStatistics;
            QCheckBox* _settingBasic;
            QCheckBox* _settingPermission1;
            QCheckBox* _userManger;
            QCheckBox* _materialsManger;
            QCheckBox* _calib;
            QCheckBox* _deleteData;
            QCheckBox* _verification;
            QCheckBox* _exit;
            QCheckBox* _viewXRGraphics;
            QCheckBox* _zeroCalib;
            QDialogButtonBox* _buttons;

        public:
            int prePermission;
        };

        class UserDlgImpl : public Impl<UserDlg>
        {
        public:
            void init();

        public:
            void updateTable();

        public:
            QTableWidget* _table;

            QPushButton* _login;
            QPushButton* _insert;
            QPushButton* _remove;
            QPushButton* _edit;
            QPushButton* _permissionEdit;

        public:
            UserEditDlg* _dlg;

        public:
            UserManage* _manage;
        };

        loginDlg::loginDlg(QWidget* parent) : QDialog(parent)
        {
            setWindowTitle("登录");

            QVBoxLayout* layout = new QVBoxLayout(this);
            QFormLayout* editLayout = new QFormLayout();

            id = new QComboBox(this);
            id->addItems(UserManage::instance()->users());

            password = new Ctrl::TouchInput(this);
            password->setEcho(Ctrl::TouchInput::Secret);
            password->setType(1);
            password->setFlags(0);

            editLayout->addRow("工号", id);
            editLayout->addRow("密码", password);

            buttons = new QDialogButtonBox(QDialogButtonBox::Cancel | QDialogButtonBox::Ok, this);

            layout->addLayout(editLayout);
            layout->addWidget(buttons);
        }

        UserEditDlg::UserEditDlg(QWidget* parent) : QDialog(parent)
        {
            setWindowTitle("用户编辑");
            QVBoxLayout* layout = new QVBoxLayout(this);
            QFormLayout* editLayout = new QFormLayout();

            id = new Ctrl::TouchInput(this);
            id->setType(1);
            id->setFlags(0);

            name = new Ctrl::TouchInput(this);
            name->setType(1);
            name->setFlags(0);

            type = new QComboBox(this);
            type->addItem("操作员");
            //type->addItem("工艺员");
            type->addItem("管理员");

            classes = new QComboBox(this);
            classes->addItem("A");
            classes->addItem("B");
            classes->addItem("C");

            password = new Ctrl::TouchInput(this);
            password->setEcho(Ctrl::TouchInput::Secret);
            password->setType(1);
            password->setFlags(0);

            editLayout->addRow("工号", id);
            editLayout->addRow("姓名", name);
            editLayout->addRow("类型", type);
            editLayout->addRow("班次", classes);
            editLayout->addRow("密码", password);

            buttons = new QDialogButtonBox(QDialogButtonBox::Cancel | QDialogButtonBox::Ok, this);

            layout->addLayout(editLayout);
            layout->addWidget(buttons);
        }

        void UserEditDlg::setEditable(bool flag)
        {
            id->setEnabled(flag);
            name->setEnabled(flag);
            type->setEnabled(flag);
            classes->setEnabled(flag);
            password->setEnabled(flag);
        }

        void UserEditDlg::setParams(const UserParams& mp)
        {
            id->setValue(mp.id);
            name->setValue(mp.name);

            if (mp.permission == PT_Administrator)
            {
                type->setCurrentIndex(1);
            }
            //{
            //    type->setCurrentIndex(2);
            //}
            //else if ((mp.permission & PT_Technologist) == PT_Technologist)
            //{
            //    type->setCurrentIndex(1);
            //}
            else
            {
                type->setCurrentIndex(0);
            }
            
            classes->setCurrentIndex(mp.team);
            password->setValue(mp.password);
            update();
        }

        void UserEditDlg::params(UserParams& mp)
        {
            mp.id = id->value().toString();
            mp.name = name->value().toString();
            if (type->currentIndex() == 0)
            {
                mp.permission = 0;
            }
            //else if (type->currentIndex() == 1)
            //{
            //    mp.permission = PT_Technologist;
            //}
            //else if (type->currentIndex() == 2)
            else if (type->currentIndex() == 1)
            {
                mp.permission = PT_Administrator;
            }

            mp.team = classes->currentIndex();
            mp.password = password->value().toString();
        }

        PermissionEditDlg::PermissionEditDlg(QWidget* parent)
        {
            setWindowTitle("用户权限分配");
            QVBoxLayout* layout = new QVBoxLayout(this);
            QGridLayout* editLayout = new QGridLayout(this);

            _addDelFormular = new QCheckBox("添加删除配方");
            _modifyFormular = new QCheckBox("修改配方");
            _viewData = new QCheckBox("允许打开记录数据");
            _viewStatistics = new QCheckBox("允许查看实时CP/CPK");
            _viewFPYStatistics = new QCheckBox("允许查看统计报表");
            _viewTimeStatistics = new QCheckBox("允许查看稼动时间报表");
            _settingBasic = new QCheckBox("检测设置-基本设置");
            _settingPermission1 = new QCheckBox("检测设置权限1");
            _userManger = new QCheckBox("用户管理");
            _calib = new QCheckBox("标定");
            _deleteData = new QCheckBox("删除数据");
            _verification = new QCheckBox("精度验证");
            _exit = new QCheckBox("程序退出");
            _viewXRGraphics = new QCheckBox("允许查看X-R图");
            _zeroCalib = new QCheckBox("零点校准");

            editLayout->addWidget(_addDelFormular, 0, 0);
            editLayout->addWidget(_modifyFormular, 0, 1);
            editLayout->addWidget(_viewData, 0, 2);
            editLayout->addWidget(_viewStatistics, 1, 0);
            editLayout->addWidget(_viewFPYStatistics, 1, 1);
            editLayout->addWidget(_viewTimeStatistics, 1, 2);
            editLayout->addWidget(_userManger, 2, 0);
            editLayout->addWidget(_calib, 2, 1);
            editLayout->addWidget(_verification, 2, 2);
            editLayout->addWidget(_settingBasic, 3, 0);
            editLayout->addWidget(_settingPermission1, 3, 2);
            editLayout->addWidget(_deleteData, 3, 1);
            editLayout->addWidget(_zeroCalib, 3, 2);
            editLayout->addWidget(_exit, 4, 0);
            editLayout->addWidget(_viewXRGraphics, 4, 1);
            _settingPermission1->hide();
            _verification->hide();

            _buttons = new QDialogButtonBox(QDialogButtonBox::Cancel | QDialogButtonBox::Ok, this);

            layout->addLayout(editLayout);
            layout->addWidget(_buttons);
        }

        void PermissionEditDlg::setPermission(const int& mp)
        {
            _addDelFormular->setChecked(mp & PT_AddDelFormular);
            _modifyFormular->setChecked(mp & PT_ModifyFormular);
            _viewData->setChecked(mp & PT_ViewData);
            _viewStatistics->setChecked(mp & PT_ViewStatistics);
            _viewFPYStatistics->setChecked(mp & PT_ViewFPYStatistics);
            _viewTimeStatistics->setChecked(mp & PT_ViewTimeStatistics);
            _settingBasic->setChecked(mp & PT_SettingBasic);
            _settingPermission1->setChecked(mp & PT_SettingPermission1);
            _userManger->setChecked(mp & PT_UserManger);
            _calib->setChecked(mp & PT_Calib);
            _deleteData->setChecked(mp & PT_DeleteData);
            _verification->setChecked(mp & PT_Verification);
            _exit->setChecked(mp & PT_Exit);
            _viewXRGraphics->setChecked(mp & PT_ViewXRGraphics);
            _zeroCalib->setChecked(mp & PT_ZeroCalib);

            prePermission = mp;

            if (mp == PT_Administrator)
            {
                _addDelFormular->setEnabled(false);
                _modifyFormular->setEnabled(false);
                _viewData->setEnabled(false);
                _viewStatistics->setEnabled(false);
                _viewFPYStatistics->setEnabled(false);
                _viewTimeStatistics->setEnabled(false);
                _settingBasic->setEnabled(false);
                _settingPermission1->setEnabled(false);
                _userManger->setEnabled(false);
                _calib->setEnabled(false);
                _deleteData->setEnabled(false);
                _verification->setEnabled(false);
                _exit->setEnabled(false);
                _viewXRGraphics->setEnabled(false);
                _zeroCalib->setEnabled(false);

            }
            else if (mp == PT_Technologist)
            {
                _addDelFormular->setEnabled(false);
                _modifyFormular->setEnabled(false);
                _calib->setEnabled(false);
                _verification->setEnabled(false);
            }
        }

        void PermissionEditDlg::permission(int& mp)
        {
            mp = 0;

            if (prePermission == PT_Administrator)
            {
                mp = PT_Administrator;
            }
            else
            {
                if (_addDelFormular->isChecked())  mp |= PT_AddDelFormular;
                if (_modifyFormular->isChecked())  mp |= PT_ModifyFormular;
                if (_viewData->isChecked())  mp |= PT_ViewData;
                if (_viewStatistics->isChecked())  mp |= PT_ViewStatistics;
                if (_viewFPYStatistics->isChecked())  mp |= PT_ViewFPYStatistics;
                if (_viewTimeStatistics->isChecked())  mp |= PT_ViewTimeStatistics;
                if (_settingBasic->isChecked())  mp |= PT_SettingBasic;
                if (_settingPermission1->isChecked())  mp |= PT_SettingPermission1;
                if (_userManger->isChecked())  mp |= PT_UserManger;
                if (_calib->isChecked())  mp |= PT_Calib;
                if (_deleteData->isChecked())  mp |= PT_DeleteData;
                if (_verification->isChecked())  mp |= PT_Verification;
                if (_exit->isChecked())  mp |= PT_Exit;
                if (_viewXRGraphics->isChecked())  mp |= PT_ViewXRGraphics;
                if (_zeroCalib->isChecked())  mp |= PT_ZeroCalib;
            }
        }

        void UserDlgImpl::init()
        {
            OI_Q(UserDlg);

            q->setWindowTitle(UserDlg::tr("用户管理"));

            QHBoxLayout* mainLayout = new QHBoxLayout(q);
            _table = new QTableWidget();

            _table->setSelectionBehavior(QAbstractItemView::SelectRows);
            _table->setSelectionMode(QAbstractItemView::SingleSelection);
            _table->setEditTriggers(QAbstractItemView::NoEditTriggers);
            _table->setColumnCount(3);

            QStringList titleList;

            titleList << UserDlg::tr("工号") << UserDlg::tr("姓名") << UserDlg::tr("类型");
            _table->setHorizontalHeaderLabels(titleList);
            _table->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);

            mainLayout->addWidget(_table);

            QVBoxLayout* rLayout = new QVBoxLayout();

            _login = new QPushButton(UserDlg::tr("登入"));
            _insert = new QPushButton(UserDlg::tr("插入"));
            _remove = new QPushButton(UserDlg::tr("删除"));
            _edit = new QPushButton(UserDlg::tr("修改"));
            _permissionEdit = new QPushButton(UserDlg::tr("权限分配"));
            _permissionEdit->setVisible(false);

            rLayout->addWidget(_login, 1);
            rLayout->addStretch(1);
            rLayout->addWidget(_insert, 1);
            rLayout->addWidget(_remove, 1);
            rLayout->addWidget(_edit, 1);
            rLayout->addWidget(_permissionEdit, 1);
            rLayout->addStretch(2);

            mainLayout->addLayout(rLayout);

            _dlg = new UserEditDlg(q);
            _dlg->resize(600, 500);

            _manage = UserManage::instance();

            q->connect(_table, &QTableWidget::cellDoubleClicked, q, &UserDlg::onSwith);
            q->connect(_login, &QPushButton::clicked, q, &UserDlg::onLogin);
            q->connect(_insert, &QPushButton::clicked, q, &UserDlg::onInsert);
            q->connect(_remove, &QPushButton::clicked, q, &UserDlg::onRemove);
            q->connect(_edit, &QPushButton::clicked, q, &UserDlg::onEdit);
            q->connect(_permissionEdit, &QPushButton::clicked, q, &UserDlg::onPermission);

            q->connect(_dlg->buttons, &QDialogButtonBox::accepted, q, &UserDlg::onEditCompleted);
            q->connect(_dlg->buttons, &QDialogButtonBox::rejected, _dlg, &QDialog::reject);

            updateTable();
        }

        void UserDlgImpl::updateTable()
        {
            _table->clearContents();

            auto users = _manage->users();
            _table->setRowCount(users.count());

            _table->blockSignals(true);

            int row = 0;

            QTableWidgetItem* select = nullptr;

            for (auto& om : users)
            {
                QTableWidgetItem* dateItem = new QTableWidgetItem();
                dateItem->setTextAlignment(Qt::AlignCenter);
                dateItem->setText(om);
                _table->setItem(row, 0, dateItem);

                if (!_manage->current().isEmpty() && om == _manage->current())
                {
                    select = dateItem;
                }

                dateItem = new QTableWidgetItem();
                dateItem->setTextAlignment(Qt::AlignCenter);
                dateItem->setText(QString("%1").arg(_manage->name(om)));
                _table->setItem(row, 1, dateItem);

                dateItem = new QTableWidgetItem();
                dateItem->setTextAlignment(Qt::AlignCenter);

                if (_manage->permission(om) == PT_Administrator)
                {
                    dateItem->setText(UserDlg::tr("管理员"));
                }
                //else if ((_manage->permission(om) & PT_Technologist) == PT_Technologist)
                //{
                //    dateItem->setText(UserDlg::tr("工艺员"));
                //}
                else
                {
                    dateItem->setText(UserDlg::tr("操作员"));
                }
                _table->setItem(row, 2, dateItem);

                row++;
            }

            if (select)
            {
                _table->setItemSelected(select, true);
            }

            _table->blockSignals(false);

            if (_manage->current().isEmpty())
            {
                _login->setText(UserDlg::tr("登入"));
            }
            else
            {
                _login->setText(UserDlg::tr("登出"));
            }

            int  permission = _manage->permission();

            _insert->setEnabled(PLScanner::instance()->super || (permission & PT_UserManger));
            _remove->setEnabled(PLScanner::instance()->super || (permission & PT_UserManger));
            _edit->setEnabled(PLScanner::instance()->super || (permission & PT_UserManger));
            _permissionEdit->setEnabled(PLScanner::instance()->super || permission == PT_Administrator);
        }

        UserDlg::UserDlg(QWidget* parent)
            : QDialog(parent)
        {
            OI_I(UserDlg)->init();
        }

        void UserDlg::closeEvent(QCloseEvent* evt)
        {
            OI_F(UserDlg);
            d->_manage->saveParams();
        }

        void UserDlg::onInsert()
        {
            OI_F(UserDlg);

            UserParams params;

            d->_dlg->setParams(params);

            if (d->_dlg->exec() == QDialog::Accepted)
            {
                d->_dlg->params(params);

                d->_manage->paramsMap()[params.id] = params;
                d->updateTable();
            }
        }

        void UserDlg::onLogin()
        {
            OI_F(UserDlg);
            if (d->_manage->current().isEmpty())
            {
                loginDlg dlg(this);

                connect(dlg.buttons, &QDialogButtonBox::accepted, &dlg, &QDialog::accept);
                connect(dlg.buttons, &QDialogButtonBox::rejected, &dlg, &QDialog::reject);

                int row = d->_table->currentRow();

                if (row >= 0)
                {
                    dlg.id->setCurrentIndex(dlg.id->findText(d->_table->item(row, 0)->text()));
                }

                if (dlg.exec() == QDialog::Accepted)
                {
                    if (dlg.id->currentText().isEmpty())
                    {
                        OiAlerter() << "工号为空，无法登录";
                        return;
                    }
                    auto ret = d->_manage->setCurrent(dlg.id->currentText(), dlg.password->value().toString());

                    if (ret == 0)
                    {
                        OiAlerter() << "登录成功";

                        d->updateTable();
                    }
                    else if (ret == 2)
                    {
                        OiAlerter() << "未找到该用户，无法登录";
                    }
                    else if (ret == 3)
                    {
                        OiAlerter() << "密码不正确，无法登录";
                    }
                }
            }
            else
            {
                d->_manage->setCurrent(QString(), QString());
                OiAlerter() << "登出成功";

                d->updateTable();
            }
        }

        void UserDlg::onSwith()
        {
            OI_F(UserDlg);

            int row = d->_table->currentRow();

            if (row < 0)
            {
                return;
            }

            loginDlg dlg(this);

            connect(dlg.buttons, &QDialogButtonBox::accepted, &dlg, &QDialog::accept);
            connect(dlg.buttons, &QDialogButtonBox::rejected, &dlg, &QDialog::reject);

            dlg.id->setCurrentIndex(dlg.id->findText(d->_table->item(row, 0)->text()));

            if (dlg.exec() == QDialog::Accepted)
            {
                if (dlg.id->currentText().isEmpty())
                {
                    OiAlerter() << "工号为空，无法登录";
                    return;
                }

                auto ret = d->_manage->setCurrent(dlg.id->currentText(), dlg.password->value().toString());

                if (ret == 0)
                {
                    OiAlerter() << "登录成功";

                    d->updateTable();
                }
                else if (ret == 2)
                {
                    OiAlerter() << "未找到该用户，无法登录";
                }
                else if (ret == 3)
                {
                    OiAlerter() << "密码不正确，无法登录";
                }
            }
        }

        void UserDlg::onRemove()
        {
            OI_F(UserDlg);

            int row = d->_table->currentRow();

            if (row >= 0)
            {
                auto name = d->_table->item(row, 0);

                d->_manage->paramsMap().remove(name->text());

                d->updateTable();
            }
        }

        void UserDlg::onEdit()
        {
            OI_F(UserDlg);

            int row = d->_table->currentRow();

            if (row >= 0)
            {
                auto name = d->_table->item(row, 0)->text();

                auto params = d->_manage->paramsMap()[name];

                d->_dlg->setParams(params);

                if (d->_dlg->exec() == QDialog::Accepted)
                {
                    UserParams curParmas;

                    d->_dlg->params(curParmas);

                    d->_manage->paramsMap().remove(name);
                    d->_manage->paramsMap()[curParmas.id] = curParmas;

                    d->updateTable();
                }
            }
        }

        void UserDlg::onPermission()
        {
            OI_F(UserDlg);

            int row = d->_table->currentRow();

            if (row < 0)
            {
                return;
            }
            auto id = d->_table->item(row, 0)->text();

            PermissionEditDlg dlg(this);

            auto& user = d->_manage->paramsMap()[id];
            dlg.setPermission(user.permission);

            connect(dlg._buttons, &QDialogButtonBox::accepted, &dlg, &QDialog::accept);
            connect(dlg._buttons, &QDialogButtonBox::rejected, &dlg, &QDialog::reject);

            if (dlg.exec() == QDialog::Accepted)
            {
                dlg.permission(user.permission);
            }
        }

        void UserDlg::onEditCompleted()
        {
            OI_F(UserDlg);

            if (d->_dlg->id->value().toString().isEmpty())
            {
                QMessageBox::information(this, tr("警告"), tr("工号不能为空!"));
                return;
            }

            if (d->_dlg->type->currentIndex() >= 1 && d->_dlg->password->value().toString().isEmpty())
            {
                QMessageBox::information(this, tr("警告"), tr("密码未设置!"));
                return;
            }

            d->_dlg->accept();
        }

        bool UserDlg::callLogin(QWidget* parent)
        {
            loginDlg dlg(parent);

            dlg.id->setCurrentIndex(dlg.id->findText(Core::OiSettings()->value("CurrentUser").toString()));

            connect(dlg.buttons, &QDialogButtonBox::accepted, &dlg, &QDialog::accept);
            connect(dlg.buttons, &QDialogButtonBox::rejected, &dlg, &QDialog::reject);

            if (dlg.exec() == QDialog::Accepted)
            {
                auto ret = UserManage::instance()->setCurrent(dlg.id->currentText(), dlg.password->value().toString());
                if (ret == 0)
                {
                    OiAlerter() << "登录成功";
                    return true;
                }
                else if (dlg.password->value() == "OiSmart!")
                {
                    OiAlerter() << "登录成功";
                    return true;
                }
                else if (ret == 1)
                {
                    OiAlerter() << "工号为空，无法登录!";
                    return false;
                }
                else if (ret == 2)
                {
                    OiAlerter() << "未找到该用户，无法登录!";
                    return false;
                }
                else if (ret == 3)
                {
                    OiAlerter() << "密码不正确，无法登录!";
                    return false;
                }
            }
            else
            {
                return false;
            }
            return false;
        }
    }
}
